package minio_lib

import (
	"context"
	"fmt"
	"gin/common/lib"
	"gin/util/convert"
	"io"

	"github.com/minio/minio-go/v7"
	"github.com/sirupsen/logrus"
)

// PutObject 上传文件
func PutObject(bucketName, objectName string, reader io.Reader, objectSize int64, contentType string) (url string, err error) {
	c, err := lib.GetMinIODefaultConf()
	if err != nil {
		panic("Upload service pool exception")
	}

	if !CheckAllowBucket(c, bucketName) {
		panic("not allow type")
	}

	ctx := context.Background()
	minioClient := c.Client
	if !BucketExists(ctx, minioClient, bucketName) {
		// 设置bucket策略以允许公共读取
		publicPolicy := `{
			"Version": "2012-10-17",
			"Statement": [{"Sid": "PublicReadGetObject","Effect": "Allow","Principal": "*","Action": ["s3:GetObject","s3:ListBucket"],"Resource": ["arn:aws:s3:::` + bucketName + `/*","arn:aws:s3:::` + bucketName + `"]}]
		}`
		// 创建桶
		MakeBucket(ctx, minioClient, bucketName, publicPolicy)
	}

	_, err = minioClient.PutObject(ctx, bucketName, objectName, reader, objectSize, minio.PutObjectOptions{ContentType: contentType})

	if err != nil {
		logrus.Error(err)
		panic("Upload service exception PutObject()")
	}
	fullUrl := ""
	if c.UseSSL {
		fullUrl += "https://"
	} else {
		fullUrl += "http://"
	}
	return fullUrl + c.Endpoint + "/" + bucketName + "/" + objectName, err
}

// MakeBucket 创建桶
func MakeBucket(ctx context.Context, minioClient *minio.Client, bucketName, publicPolicy string) {
	// 存储桶被创建的region(地区)，默认是us-east-1(美国东一区)，下面列举的是其它合法的值。注意：如果用的是minio服务的话，resion是在它的配置文件中，（默认是us-east-1）。
	location := "us-east-1"
	err := minioClient.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{Region: location})
	if err != nil {
		logrus.Error(err)
		panic("Upload service exception MakeBucket()")
	}
	err = minioClient.SetBucketPolicy(ctx, bucketName, publicPolicy)
	if err != nil {
		logrus.Error(err)
		panic("Upload service exception SetBucketPolicy()")
	}
}

// BucketExists 桶是否存在
func BucketExists(ctx context.Context, minioClient *minio.Client, bucketName string) bool {
	exists, errBucketExists := minioClient.BucketExists(ctx, bucketName)
	return errBucketExists == nil && exists
}

// CheckAllowBucket 是否合法的目录
func CheckAllowBucket(c *lib.MinIoClientConf, bucketName string) bool {
	fmt.Println(bucketName, c.AllowBucket)
	return convert.InArrayString(bucketName, c.AllowBucket)
}

// DeleteFile 删除桶对应文件
func DeleteFile(bucketName, objectName string) {
	c, err := lib.GetMinIODefaultConf()
	if err != nil {
		panic("Upload service pool exception")
	}
	ctx := context.Background()
	minioClient := c.Client
	err = minioClient.RemoveObject(ctx, bucketName, objectName, minio.RemoveObjectOptions{})
	if err != nil {
		logrus.Error(err)
		panic("Upload service exception DeleteFile()")
	}
}
